package com.ruoyi.doorcontrol.Acs;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;

import com.ruoyi.doorcontrol.domain.ThDoorcontrolUser;
import com.ruoyi.doorcontrol.sdk.HCNetSDK;
import com.sun.jna.ptr.IntByReference;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class UserControl {
    static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;

    /**
     * 查询人员信息
     * @param userID
     * @throws JSONException
     */
    public static List<com.alibaba.fastjson2.JSONObject> searchUserInfo(int userID,String str_employeeNo) throws JSONException {
        List<com.alibaba.fastjson2.JSONObject> list = new ArrayList<>();
        HCNetSDK.BYTE_ARRAY ptrByteArray = new HCNetSDK.BYTE_ARRAY(1024);    //数组
        String strInBuffer = "POST /ISAPI/AccessControl/UserInfo/Search?format=json";
        System.arraycopy(strInBuffer.getBytes(), 0, ptrByteArray.byValue, 0, strInBuffer.length());//字符串拷贝到数组中
        ptrByteArray.write();

        int lHandler = hCNetSDK.NET_DVR_StartRemoteConfig(userID, HCNetSDK.NET_DVR_JSON_CONFIG, ptrByteArray.getPointer(), strInBuffer.length(), null, null);
        if (lHandler < 0) {
            System.out.println("SearchUserInfo NET_DVR_StartRemoteConfig 失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
            return list;
        } else {
            //组装查询的JSON报文，这边查询的是所有的人员
            JSONObject jsonObject = new JSONObject();
            JSONObject jsonSearchCond = new JSONObject();


	        if(StringUtils.isNotBlank(str_employeeNo)){
                JSONArray EmployeeNoList = new JSONArray();
                String[] employeeNo = str_employeeNo.split(",");
                for (String eno:employeeNo){
                    JSONObject employee = new JSONObject();
                    employee.put("employeeNo", eno);
                    EmployeeNoList.put(employee);
                }
                jsonSearchCond.put("EmployeeNoList",EmployeeNoList);
            }


            jsonSearchCond.put("searchID", "20211126");
            jsonSearchCond.put("searchResultPosition", 0);
            jsonSearchCond.put("maxResults", 50);
            jsonObject.put("UserInfoSearchCond", jsonSearchCond);

            String strInbuff = jsonObject.toString();
            System.out.println("查询的json报文:" + strInbuff);

            //把string传递到Byte数组中，后续用.getPointer()方法传入指针地址中。
            HCNetSDK.BYTE_ARRAY ptrInbuff = new HCNetSDK.BYTE_ARRAY(strInbuff.length());
            System.arraycopy(strInbuff.getBytes(), 0, ptrInbuff.byValue, 0, strInbuff.length());
            ptrInbuff.write();

            //定义接收结果的结构体
            HCNetSDK.BYTE_ARRAY ptrOutuff = new HCNetSDK.BYTE_ARRAY(10 * 1024);

            IntByReference pInt = new IntByReference(0);

            while (true) {
                /*
                dwOutBuffSize是输出缓冲区大小，需要自定义指定大小，如果接口报错错误码43.说明接收设备数据的缓冲区或存放图片缓冲区不足，应扩大缓冲区大小
                 */
                //int dwState = AcsMain.hCNetSDK.NET_DVR_SendWithRecvRemoteConfig(lHandler, ptrInbuff.getPointer(), strInbuff.length(), ptrOutuff.getPointer(), 20 * 1024, pInt);
                int dwState = hCNetSDK.NET_DVR_SendWithRecvRemoteConfig(lHandler, ptrInbuff.getPointer(), strInbuff.length(), ptrOutuff.getPointer(), 20 * 1024, pInt);
                System.out.println(dwState);
                if (dwState == -1) {
                    System.out.println("NET_DVR_SendWithRecvRemoteConfig接口调用失败，错误码：" + hCNetSDK.NET_DVR_GetLastError());
                    break;
                } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_NEED_WAIT) {
                    System.out.println("配置等待");
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    continue;
                } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FAILED) {
                    System.out.println("查询人员失败");
                    break;
                } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_EXCEPTION) {
                    System.out.println("查询人员异常");
                    break;
                } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_SUCCESS) {
                    ptrOutuff.read();
                    String UserInfoSearch = new String(ptrOutuff.byValue).trim();
                    com.alibaba.fastjson2.JSONObject jsonObject_userinfoSearch = JSON.parseObject(UserInfoSearch);
                    String userInfoSearch = jsonObject_userinfoSearch.getString("UserInfoSearch");
                    com.alibaba.fastjson2.JSONObject jsonObject_userInfo = JSON.parseObject(userInfoSearch);
                    com.alibaba.fastjson2.JSONArray jsona = com.alibaba.fastjson2.JSONArray.parse(jsonObject_userInfo.getString("UserInfo"));
                    System.out.println("查询人员:"+jsona);
                    for (int i = 0; i < jsona.size(); i++) {
                        list.add(jsona.getJSONObject(i));
                    }
                    return list;
                    //System.out.println("查询人员成功, json:" + new String(ptrOutuff.byValue).trim());
                    //break;
                } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FINISH) {
                    System.out.println("获取人员完成");
                    break;
                }
            }

            //if (!AcsMain.hCNetSDK.NET_DVR_StopRemoteConfig(lHandler)) {
            if (!hCNetSDK.NET_DVR_StopRemoteConfig(lHandler)) {
                //System.out.println("NET_DVR_StopRemoteConfig接口调用失败，错误码：" + AcsMain.hCNetSDK.NET_DVR_GetLastError());
                System.out.println("NET_DVR_StopRemoteConfig接口调用失败，错误码：" + hCNetSDK.NET_DVR_GetLastError());
            } else {
                System.out.println("NET_DVR_StopRemoteConfig接口成功");
                lHandler = -1;
            }
        }

      return list;
    }

    public static String deleteUserInfo(int userID,String employeeNo) throws JSONException {

        String deleteUserjson = "";
        if(StringUtils.isNotBlank(employeeNo)){
             deleteUserjson="{\n" +
                "\t\"UserInfoDetail\": {\t\n" +
                "\t\t\"mode\":  \"byEmployeeNo\",\t\n" +
                "\t\t\"EmployeeNoList\": [\t\n" +
                "\t\t\t{\n" +
                "\t\t\t\t\"employeeNo\":  \""+employeeNo+"\"\t\n" +
                "\t\t\t}\n" +
                "\t\t]\n" +
                "\n" +
                "\t}\n" +
                "}";
        }else {
             deleteUserjson = "{\n" +
                "\t\"UserInfoDetail\": {\t\n" +
                "\t\t\"mode\":  \"all\",\t\n" +
                "\t\t\"EmployeeNoList\": [\t\n" +
                "\t\t]\n" +
                "\n" +
                "\t}\n" +
                "}";
        }
        System.out.println("删除用户deleteUserjson="+deleteUserjson);
        String deleteUserUrl = "PUT /ISAPI/AccessControl/UserInfoDetail/Delete?format=json";
        String result = TransIsapi.put_isapi(userID, deleteUserUrl, deleteUserjson);
        System.out.println(result);
        //获取删除进度
        while (true) {
            String getDeleteProcessUrl = "GET /ISAPI/AccessControl/UserInfoDetail/DeleteProcess?format=json";
            String deleteResult = TransIsapi.get_isapi(userID, getDeleteProcessUrl);
            JSONObject jsonObject = new JSONObject(deleteResult);
            JSONObject jsonObject1 = jsonObject.getJSONObject("UserInfoDetailDeleteProcess");
            String process = jsonObject1.getString("status");
            System.out.println("process ="+process);
            return process;
            /*if (process.equals("processing")) {
                System.out.println("正在删除");
                continue;
            } else if (process.equals("success")) {
                System.out.println("删除成功");
                break;
            }else if(process.equals("failed")){
                System.out.println("删除失败");
                break;
            }*/
        }
    }

    public static AjaxResult addUser(int lUserID, ThDoorcontrolUser thDoorcontrolUser) throws UnsupportedEncodingException, InterruptedException, JSONException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        System.out.println("beginTime="+thDoorcontrolUser.getBeginTime());
        System.out.println("sdf-beginTime="+sdf.format(thDoorcontrolUser.getBeginTime()));
        AjaxResult ajaxResult = new AjaxResult();
        HCNetSDK.BYTE_ARRAY ptrByteArray = new HCNetSDK.BYTE_ARRAY(1024);    //数组
        //"POST /ISAPI/AccessControl/UserInfo/Record?format=json" 此URL也是下发人员
        String strInBuffer = "PUT /ISAPI/AccessControl/UserInfo/SetUp?format=json";
        System.arraycopy(strInBuffer.getBytes(), 0, ptrByteArray.byValue, 0, strInBuffer.length());//字符串拷贝到数组中
        ptrByteArray.write();

        int lHandler = hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_JSON_CONFIG, ptrByteArray.getPointer(), strInBuffer.length(), null, null);
        if (lHandler < 0) {
            System.out.println("AddUserInfo NET_DVR_StartRemoteConfig 失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
            ajaxResult.put("code", HttpStatus.ERROR);
            ajaxResult.put("msg","AddUserInfo NET_DVR_StartRemoteConfig 失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
            return ajaxResult;
        } else {
            System.out.println("AddUserInfo NET_DVR_StartRemoteConfig 成功!");

            byte[] Name = thDoorcontrolUser.getUname().getBytes("utf-8"); //根据iCharEncodeType判断，如果iCharEncodeType返回6，则是UTF-8编码。
            //如果是0或者1或者2，则是GBK编码

            //将中文字符编码之后用数组拷贝的方式，避免因为编码导致的长度问题
            String strInBuffer1 = "{\n" +
                    "    \"UserInfo\":{\n" +
                    "        \"employeeNo\":\""+thDoorcontrolUser.getEmployeeNo()+"\",\n" +
                    "        \"name\":\"";
            String strInBuffer2 = "\",\n" +
                    "        \"userType\":\""+thDoorcontrolUser.getUserType()+"\",\n" +
                    "        \"Valid\":{\n" +
                    "            \"enable\":"+thDoorcontrolUser.getEnable()+",\n" +
                    "            \"beginTime\":\""+sdf.format(thDoorcontrolUser.getBeginTime())+"\",\n" +
                    "            \"endTime\":\""+sdf.format(thDoorcontrolUser.getEndTime())+"\",\n" +
                    "            \"timeType\":\"local\"\n" +
                    "        },\n" +
                    "        \"belongGroup\":\"1\",\n" +
                    "        \"doorRight\":\"1\",\n" +
                    "        \"RightPlan\":[\n" +
                    "            {\n" +
                    "                \"doorNo\":1,\n" +
                    "                \"planTemplateNo\":\"1\"\n" +
                    "            }\n" +
                    "        ]\n" +
                    "    }\n" +
                    "}";
            int iStringSize = Name.length + strInBuffer1.length() + strInBuffer2.length();

            HCNetSDK.BYTE_ARRAY ptrByte = new HCNetSDK.BYTE_ARRAY(iStringSize);
            System.arraycopy(strInBuffer1.getBytes(), 0, ptrByte.byValue, 0, strInBuffer1.length());
            System.arraycopy(Name, 0, ptrByte.byValue, strInBuffer1.length(), Name.length);
            System.arraycopy(strInBuffer2.getBytes(), 0, ptrByte.byValue, strInBuffer1.length() + Name.length, strInBuffer2.length());
            ptrByte.write();

            System.out.println(new String(ptrByte.byValue));

            HCNetSDK.BYTE_ARRAY ptrOutuff = new HCNetSDK.BYTE_ARRAY(1024);

            IntByReference pInt = new IntByReference(0);
            while (true) {
                int dwState = hCNetSDK.NET_DVR_SendWithRecvRemoteConfig(lHandler, ptrByte.getPointer(), iStringSize, ptrOutuff.getPointer(), 1024, pInt);
                if (dwState == -1) {
                    System.out.println("NET_DVR_SendWithRecvRemoteConfig接口调用失败，错误码：" + hCNetSDK.NET_DVR_GetLastError());
                    break;
                }
                //读取返回的json并解析
                ptrOutuff.read();
                String strResult = new String(ptrOutuff.byValue).trim();
                System.out.println("dwState:" + dwState + ",strResult:" + strResult);

                JSONObject jsonResult = new JSONObject(strResult);
                int statusCode = jsonResult.getInt("statusCode");
                String statusString = jsonResult.getString("statusString");
                if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_NEED_WAIT) {
                    System.out.println("配置等待");
                    Thread.sleep(10);
                    ajaxResult.put("code", HttpStatus.ACCEPTED);
                    ajaxResult.put("msg","配置等待");
                    continue;
                } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FAILED) {
                    System.out.println("下发人员失败, json retun:" + jsonResult.toString());
                    ajaxResult.put("code", HttpStatus.ERROR);
                    ajaxResult.put("msg","下发人员失败");
                    break;
                } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_EXCEPTION) {
                    System.out.println("下发人员异常, json retun:" + jsonResult.toString());
                    ajaxResult.put("code", HttpStatus.ERROR);
                    ajaxResult.put("msg","下发人员失败");
                    break;
                } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_SUCCESS) {//返回NET_SDK_CONFIG_STATUS_SUCCESS代表流程走通了，但并不代表下发成功，比如有些设备可能因为人员已存在等原因下发失败，所以需要解析Json报文
                    if (statusCode != 1) {
                        System.out.println("下发人员成功,但是有异常情况:" + jsonResult.toString());
                        ajaxResult.put("code", HttpStatus.SUCCESS_ERROR);
                        ajaxResult.put("msg","下发人员成功,但是有异常情况");
                    } else {
                        System.out.println("下发人员成功: json retun:" + jsonResult.toString());
                        ajaxResult.put("code", HttpStatus.SUCCESS);
                        ajaxResult.put("msg","下发人员成功");
                    }
                    break;
                } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FINISH) {
                    //下发人员时：dwState其实不会走到这里，因为设备不知道我们会下发多少个人，所以长连接需要我们主动关闭
                    System.out.println("下发人员完成");
                    break;
                }
            }
            if (!hCNetSDK.NET_DVR_StopRemoteConfig(lHandler)) {
                System.out.println("NET_DVR_StopRemoteConfig接口调用失败，错误码：" + hCNetSDK.NET_DVR_GetLastError());
            } else {
                System.out.println("NET_DVR_StopRemoteConfig接口成功");
            }
            return ajaxResult;
        }
    }
}
